package net.cassite.pure.ioc.handlers.type;

import java.lang.annotation.Annotation;

import net.cassite.pure.ioc.*;
import net.cassite.pure.ioc.annotations.Wire;
import net.cassite.pure.ioc.handlers.TypeAnnotationHandler;
import net.cassite.pure.ioc.handlers.TypeHandlerChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Handler for Wire annotation. <br>
 * if the class extends from AutoWire, this would simply return <br>
 * else, all setters would be autowired.
 *
 * @author wkgcass
 * @see Wire
 */
public class TypeWireHandler extends IOCController implements TypeAnnotationHandler {

        private static final Logger LOGGER = LoggerFactory.getLogger(TypeWireHandler.class);

        @Override
        public boolean canHandle(Annotation[] annotations) {
                for (Annotation ann : annotations) {
                        if (ann.annotationType() == Wire.class) {
                                return true;
                        }
                }
                return false;
        }

        @Override
        public Object handle(Scope scope, Class<?> cls, TypeHandlerChain chain) throws AnnotationHandlingException {
                LOGGER.debug("Entered TypeWireHandler with args: \n\tcls:\t{}\n\tchain:\t{}", cls, chain);
                Object inst = chain.next().handle(scope, cls, chain);

                LOGGER.debug("start handling with TypeWireHandler");
                if (!AutoWire.class.isAssignableFrom(cls)) {
                        try {
                                AutoWire.wire(scope, inst);
                        } catch (ConstructingMultiSingletonException ignore) {
                        }
                }
                /*******************************
                 LOGGER.debug("--start wiring setters");
                 // setters
                 net.cassite.style.ptr<Object> $inst = ptr(inst);
                 cls(inst.getClass()).setters().forEach(m -> invokeSetter(scope, $($inst), m));
                 LOGGER.debug("--finished wiring setters");
                 *******************************
                 LOGGER.debug("--start invoking methods");
                 // invoke
                 cls(inst.getClass()).allMethods().forEach(m -> {
                 if (m.isAnnotationPresent(Invoke.class) && !m.isStatic()) {
                 invokeMethod(scope, m, $($inst));
                 }
                 });
                 LOGGER.debug("--finished invoking methods");
                 */
                return inst;
        }

}
